package org.bim.view.drag.design.controller;


import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Splitter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.bim.view.drag.design.api.dto.VisualDTO;
import org.bim.view.drag.design.api.req.VisualReq;
import org.bim.view.drag.design.api.vo.IdVO;
import org.bim.view.drag.design.api.vo.TUserVO;
import org.bim.view.drag.design.constant.CommonConstant;
import org.bim.view.drag.design.dao.BladeFileMapper;
import org.bim.view.drag.design.dao.VisualCategoryMapper;
import org.bim.view.drag.design.dao.VisualConfigMapper;
import org.bim.view.drag.design.dao.VisualMapper;
import org.bim.view.drag.design.entity.TBladeFile;
import org.bim.view.drag.design.entity.TVisual;
import org.bim.view.drag.design.entity.TVisualCategory;
import org.bim.view.drag.design.entity.TVisualConfig;
import org.bim.view.drag.design.model.HttpResult;
import org.bim.view.drag.design.model.Page;
import org.bim.view.drag.design.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author pengxg
 * @date 2021/12/16 4:47 下午
 */
@Slf4j
@Api
@RestController
@RequestMapping("visual")
public class VisualController {
    @Resource
    private VisualMapper visualMapper;
    @Resource
    private VisualConfigMapper visualConfigMapper;
    @Resource
    private VisualCategoryMapper visualCategoryMapper;
    @Resource
    private BladeFileMapper bladeFileMapper;

    /**
     * 本地：local，Minio：minio，阿里云：alioss,恒嘉 oss： hj-oss
     */
    @Value(value = "${app.upload.mode}")
    private String uploadType;
    @Value(value = "${app.upload.base-upload-path}")
    private String uploadPath;

    @GetMapping("detail")
    public HttpResult<VisualDTO> detail(@RequestParam String id) {
        TVisual visual = visualMapper.selectByPrimaryKey(id);
        TVisualConfig visualConfig = visualConfigMapper.selectOne(TVisualConfig.initWithVisualId(id));
        return HttpResult.success(new VisualDTO(visual, visualConfig));
    }

    @GetMapping("list")
    public HttpResult<Page<TVisual>> page(VisualReq req) {
        TUserVO userVO = ThreadLocalUtil.getCurrentUser();
        Page<TVisual> page = PageUtil.doPage(req.toCondition(), () -> {
            Example example = new Example(TVisual.class, false);
            Example.Criteria criteria = example.createCriteria()
                    .andEqualTo("isDeleted", false)
                    .andEqualTo("category", req.getCategory())
                    .andEqualTo("status", req.getStatus())
                    .andLike("title", req.getTitle())
                    .andEqualTo("projectId", req.getProjectId());
            if (!userVO.isAdmin()) {
                if(StringUtils.isEmpty(req.getProjectId())){
                    criteria.andEqualTo("ownerId", userVO.getId());
                }
            }
            example.orderBy("createTime").desc();
            return visualMapper.selectByExample(example);
        });
        return HttpResult.success(page);
    }

    @Transactional
    @PostMapping("save")
    public HttpResult<IdVO> save(@RequestBody VisualDTO form) {
        TUserVO userVO = ThreadLocalUtil.getCurrentUser();
        TVisual visual = form.getVisual();
        visual.setOwnerId(userVO.getId());
        TVisualConfig visualConfig = form.getConfig();
        visualMapper.insertSelective(visual);
        visualConfig.setVisualId(visual.getId());
        visualConfigMapper.insertSelective(visualConfig);
        return HttpResult.success(new IdVO(visual.getId()));
    }

    @Transactional
    @PostMapping("update")
    public HttpResult<IdVO> update(@RequestBody VisualDTO form) {
        TVisual visual = form.getVisual();
        AssertUtil.isTrue(Objects.nonNull(visual), "visual不能为空");
        AssertUtil.isTrue(Objects.nonNull(visual.getId()), "更新时id不能为空");
        TVisualConfig visualConfig = form.getConfig();
        if (visualConfig == null) {
            visualMapper.updateByPrimaryKeySelective(visual);
        } else {
            AssertUtil.isTrue(Objects.nonNull(visualConfig.getId()), "更新时id不能为空");
            AssertUtil.isTrue(Objects.equals(visual.getId(), visualConfig.getVisualId()), "数据不一致");
            visualMapper.updateByPrimaryKeySelective(visual);
            visualConfigMapper.updateByPrimaryKeySelective(visualConfig);
        }

        return HttpResult.success(new IdVO(visual.getId()));
    }

    @Transactional
    @PostMapping("remove")
    public HttpResult remove(@RequestParam String ids) {
        Splitter.on(",").split(ids).forEach(id -> {
            TVisual visual = visualMapper.selectByPrimaryKey(id);
            AssertUtil.isTrue(Objects.nonNull(visual), "对象不存在");
            visual.setIsDeleted(true);
            visualMapper.updateByPrimaryKeySelective(visual);
        });
        return HttpResult.success();
    }


    @PostMapping("copy/{id}")
    public HttpResult<String> copy(@ApiParam(required = true, value = "原大屏Id") @PathVariable String id, @RequestBody TVisual data) {
        TUserVO userVO = ThreadLocalUtil.getCurrentUser();
        TVisual visual = visualMapper.selectByPrimaryKey(id);
        AssertUtil.isTrue(Objects.nonNull(visual), "数据不存在");

        TVisual copyVisual = new TVisual();
        BeanUtils.copyProperties(visual, copyVisual, new CopyOptions().setIgnoreProperties("id", "createTime", "createUser", "updateTime", "updateUser"));
        BeanUtils.copyProperties(data, copyVisual, new CopyOptions().setIgnoreProperties("id", "createTime", "createUser", "updateTime", "updateUser"));
        copyVisual.setOwnerId(userVO.getId());
        visualMapper.insertSelective(copyVisual);

        TVisualConfig visualConfig = visualConfigMapper.selectOne(TVisualConfig.initWithVisualId(id));
        TVisualConfig copyVisualConfig = new TVisualConfig();
        BeanUtils.copyProperties(visualConfig, copyVisualConfig, new CopyOptions().setIgnoreProperties("id"));
        copyVisualConfig.setVisualId(copyVisual.getId());
        visualConfigMapper.insertSelective(copyVisualConfig);

        return HttpResult.success(copyVisual.getId());
    }



    @GetMapping("category")
    public HttpResult<List<TVisualCategory>> list(TVisualCategory req) {
        List<TVisualCategory> result =new ArrayList<>();
        // 区分不同用户
        TUserVO userVO = ThreadLocalUtil.getCurrentUser();
        Example example = new Example(TVisualCategory.class,false);
        if(userVO.isAdmin()){
            if(StringUtils.isEmpty(req.getProjectId())){
                example.createCriteria().andIsNull("ownerId")
                        .orEqualTo("ownerId",userVO.getId());
                result = visualCategoryMapper.selectByExample(example);
            }else {
                example.createCriteria()
                        .andEqualTo("projectId",req.getProjectId());
                result = visualCategoryMapper.selectByExample(example);
            }
        }else {
            example.createCriteria()
                    .andEqualTo("ownerId",userVO.getId())
                    .andEqualTo("projectId",req.getProjectId());
            result = visualCategoryMapper.selectByExample(example);
        }
        return HttpResult.success(result);
    }



    @PostMapping("put-file")
    public HttpResult<TBladeFile> upload(MultipartFile file, HttpServletRequest request) {
        String originalName = file.getOriginalFilename();
        String savePath;
        if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
            savePath = this.uploadLocal(file, "files");
        } else {
            savePath = CommonUtils.upload(file, uploadType);
        }

        log.info("获取参数:{}", JSON.toJSONString(request.getParameterMap()));
        TBladeFile bladeFile = new TBladeFile();
        bladeFile.setDomain(CommonUtils.getUploadDomain(uploadType));
        bladeFile.setLink(savePath);
        bladeFile.setName(originalName);
        bladeFile.setOriginalName(originalName);
        String visualId = request.getParameter("visualId");
        String projectId = request.getParameter("projectId");
        String typeStr = request.getParameter("type");

        if(!StringUtils.isEmpty(typeStr)&&!StringUtils.isEmpty(visualId)){
            bladeFile.setVisualId(visualId);
            bladeFile.setType(Integer.parseInt(typeStr));
            // 如果有这两个参数
            if(!StringUtils.isEmpty(projectId)){
                bladeFile.setProjectId(projectId);
            }
        }
        bladeFileMapper.insertSelective(bladeFile);

        return HttpResult.success(bladeFile);
    }
    @GetMapping("images")
    public HttpResult<List<TBladeFile>> images(String visualId,String projectId,Integer type){
        Example example =new Example(TBladeFile.class);
        example.selectProperties("id","name","domain","link","projectId","visualId","type");
        Example.Criteria criteria =example.createCriteria()
                .andEqualTo("projectId",projectId)
                .andEqualTo("type",type);
        if(StringUtils.isEmpty(projectId)){
            criteria.andEqualTo("visualId",visualId);
        }
        List<TBladeFile> files = bladeFileMapper.selectByExample(example);
        return HttpResult.success(files);
    }

    private String uploadLocal(MultipartFile mf, String bizPath) {
        try {
            String ctxPath = uploadPath;
            String fileName = null;
            File file = new File(ctxPath + File.separator + bizPath + File.separator);
            if (!file.exists()) {
                file.mkdirs();// 创建文件根目录
            }
            String orgName = mf.getOriginalFilename();// 获取文件名
            orgName = CommonUtils.getFileName(orgName);
            if (orgName.contains(".")) {
                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
            } else {
                fileName = orgName + "_" + System.currentTimeMillis();
            }
            String savePath = file.getPath() + File.separator + fileName;
            File savefile = new File(savePath);
            FileCopyUtils.copy(mf.getBytes(), savefile);
            String dbpath = "/";
            if (StringUtils.hasLength(bizPath)) {
                dbpath += bizPath + File.separator + fileName;
            } else {
                dbpath += fileName;
            }
            if (dbpath.contains("\\")) {
                dbpath = dbpath.replace("\\", "/");
            }
            return dbpath;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }
}
